package com.oto.service;

import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.wltea.analyzer.IKSegmentation;
import org.wltea.analyzer.Lexeme;

import com.oto.model.IndexDO;

/**
 * @author xueqiang.mi
 * @since 2011-1-16
 */
@Service
public class SearchService extends BaseService {

	@Autowired
	protected IndexService indexService;

	/**
	 * 返回对搜索关键字字符串切记后得到的关键字集合
	 * 
	 * @param key
	 *          搜索关键字字符串
	 * @return 关键字集合
	 */
	public Collection<String> parse(String key) {
		Reader input = new StringReader(key);
		IKSegmentation segmentation = new IKSegmentation(input);
		List<String> keys = new ArrayList<String>();
		try {
			Lexeme lexeme = segmentation.next();
			while (lexeme != null) {
				keys.add(lexeme.getLexemeText());
				lexeme = segmentation.next();
			}
		} catch (IOException e) {
			// Ignore
		}
		return keys;
	}

	/**
	 * 搜索服务，使用关键字集合进行搜索
	 * 
	 * @param keys
	 *          关键字集合
	 * @param resultNumber
	 *          期望的搜索结果个数
	 * @return 搜索结果
	 */
	public <T> List<T> search(Class<T> clazz, Collection<String> keys, int resultNumber) {
		Map<Long, Integer> hitMap = new HashMap<Long, Integer>();
		List<String> hitKeys = new ArrayList<String>(); // 将有命中记录的关键字存放在此
		for (String key : keys) {
			boolean invalid = false;
			for (String hitKey : hitKeys) {
				if (hitKey.contains(key)) {
					invalid = true;
					break;
				}
			}
			if (invalid) {
				continue;
			}

			IndexDO indexDO = indexService.getIndex(key);
			if (indexDO != null) {
				hitKeys.add(key);
				Set<Long> objIds = indexDO.getObjs();
				stat(hitMap, objIds);
			}
		}

		// 排序objId列表
		List<Map.Entry<Long, Integer>> entries = new ArrayList<Map.Entry<Long, Integer>>(hitMap.entrySet());
		Collections.sort(entries, new Comparator<Map.Entry<Long, Integer>>() {
			@Override
			public int compare(Entry<Long, Integer> o1, Entry<Long, Integer> o2) {
				return o2.getValue() - o1.getValue();
			}
		});

		// 查询出搜索结果中排名前N的objList
		List<T> result = new ArrayList<T>();
		for (int i = 0; i < resultNumber && i < entries.size(); i++) {
			T obj = get(clazz, entries.get(i).getKey());
			result.add(obj);
		}
		return result;
	}

	private void stat(Map<Long, Integer> hitMap, Set<Long> ids) {
		for (Long id : ids) {
			if (hitMap.containsKey(id)) {
				hitMap.put(id, hitMap.get(id) + 1);
			} else {
				hitMap.put(id, 1);
			}
		}
	}
}
